﻿/* Copyright (C) 2007-2010 STS Soft

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

using System;
using System.Collections.Generic;
using System.Text;
using STSdb.General.Buffers;
using System.IO;
using System.Linq;

namespace STSdb.General.Buffers
{
    public sealed class BinaryBuffer : IEquatable<BinaryBuffer>, ICloneable, IComparable<BinaryBuffer>
    {
        private int? hashCode;

        public readonly byte[] Raw;

        public unsafe BinaryBuffer(byte[] raw)
        {
            this.Raw = raw;
        }

        public override int GetHashCode()
        {
            if (hashCode == null)
                hashCode = ArrayExtensions.GetHashCode(Raw);

            return hashCode.Value;
        }

        public override bool Equals(object obj)
        {
            if (!(obj is BinaryBuffer))
                return false;

            return Equals((BinaryBuffer)obj);
        }

        #region IEquatable<BinaryBuffer> Members

        public unsafe bool Equals(BinaryBuffer other)
        {
            //if (GetHashCode() != other.GetHashCode())
            //    return false;

            return Raw.EqualsТо(other.Raw);
        }

        #endregion

        #region Operators

        public static bool operator ==(BinaryBuffer a, BinaryBuffer b)
        {
            if (Object.ReferenceEquals(a, b))
                return true;

            if (Object.ReferenceEquals(a, null))
                return false;

            return a.Equals(b);
        }

        public static bool operator !=(BinaryBuffer a, BinaryBuffer b)
        {
            return !(a == b);
        }

        public static bool operator <(BinaryBuffer a, BinaryBuffer b)
        {
            return a.CompareTo(b) < 0;
        }

        public static bool operator <=(BinaryBuffer a, BinaryBuffer b)
        {
            return a.CompareTo(b) <= 0;
        }

        public static bool operator >(BinaryBuffer a, BinaryBuffer b)
        {
            return a.CompareTo(b) > 0;
        }

        public static bool operator >=(BinaryBuffer a, BinaryBuffer b)
        {
            return a.CompareTo(b) >= 0;
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            return new BinaryBuffer((byte[])Raw.Clone());
        }

        #endregion

        #region IComparable<BinaryBuffer> Members

        public int CompareTo(BinaryBuffer other)
        {
            //return Raw.CompareTo(other.Raw);
            return Raw.ReverseCompareTo(other.Raw);
        }

        #endregion

        public override string ToString()
        {
            return String.Format("[{0}]", String.Join(", ", Raw.Select(x => x.ToString()).ToArray()));
        }
    }
}
